From dea3f61b59084b48e48515d999d6d908e32341aa Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Mon, 21 Dec 2009 10:48:01 +0000 Subject: [PATCH] Check m2p/compat m2p table for new added memory. As we allocate m2p/compat m2p/frametable page tables from new added memory, we want to make sure the new range can hold up the new page tables, this is because m2p/frametable need be aligned and cover more than the new-added range. Signed-off-by: Jiang, Yunhong --- xen/arch/x86/x86_64/mm.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/xen/arch/x86/x86_64/mm.c b/xen/arch/x86/x86_64/mm.c index a6954c743e..dfa12ad171 100644 --- a/xen/arch/x86/x86_64/mm.c +++ b/xen/arch/x86/x86_64/mm.c @@ -1332,6 +1332,8 @@ int transfer_pages_to_heap(struct mem_hotadd_info *info) int mem_hotadd_check(unsigned long spfn, unsigned long epfn) { + unsigned long s, e, length; + if ( (spfn >= epfn) || (spfn < max_page) ) return 0; @@ -1341,7 +1343,31 @@ int mem_hotadd_check(unsigned long spfn, unsigned long epfn) if ( (spfn | epfn) & pfn_hole_mask ) return 0; - /* TBD: Need make sure cover to m2p/ft page table */ + /* Caculate at most required m2p/compat m2p/frametable pages */ + s = (spfn & ~((1UL << (L2_PAGETABLE_SHIFT - 3)) - 1)); + e = (epfn + (1UL << (L2_PAGETABLE_SHIFT - 3)) - 1) & + ~((1UL << (L2_PAGETABLE_SHIFT - 3)) - 1); + + length = (e - s) * sizeof(unsigned long); + + s = (spfn & ~((1UL << (L2_PAGETABLE_SHIFT - 2)) - 1)); + e = (epfn + (1UL << (L2_PAGETABLE_SHIFT - 2)) - 1) & + ~((1UL << (L2_PAGETABLE_SHIFT - 2)) - 1); + + e = min_t(unsigned long, e, + (RDWR_COMPAT_MPT_VIRT_END - RDWR_COMPAT_MPT_VIRT_START) >> 2); + + if ( e > s ) + length += (e -s) * sizeof(unsigned int); + + s = pfn_to_pdx(spfn) & ~(PDX_GROUP_COUNT - 1); + e = ( pfn_to_pdx(epfn) + (PDX_GROUP_COUNT - 1) ) & ~(PDX_GROUP_COUNT - 1); + + length += (e - s) * sizeof(struct page_info); + + if ((length >> PAGE_SHIFT) > (epfn - spfn)) + return 0; + return 1; } -- 2.30.2